package cscalendar.classes;

import cscalendar.exceptions.CSCommandNotFoundException;
import cscalendar.exceptions.CSWrongCommandFormatException;
import cscalendar.interfaces.IExecutable;
import java.util.HashMap;



/**
 *
 * @author Muhammad Anis
 */
public class CSCommand {
    CSCalendar myCalendar;
    HashMap<String, IExecutable> myCommands;
    
    /**
     * Create Command for particular Calendar
     * @param calendar calendar with command
     */
    public CSCommand(CSCalendar calendar){
        this.myCalendar = calendar;
        this.myCommands = new HashMap<>();
        buildCommand();
    }
    
    /**
     * Add a command to collection
     * @param commandName name of command
     * @param executable interface of executable class
     */
    public void AddCommand(String commandName,IExecutable executable){
        this.myCommands.put(commandName, executable);
    }
    
    /**
     * Execute a command
     * @param commandName name of command
     * @param args argument for executing command
     * @throws CSCommandNotFoundException if command name doesn't exist in collection
     */
    public void Execute(String commandName, String[] args) throws CSCommandNotFoundException{
        IExecutable executable = this.myCommands.get(commandName);
        if(executable != null){
            executable.Execute(args);
        }else{
            throw new CSCommandNotFoundException("Command "+commandName +" is not defined");
        }
    }

    /**
     * Build all command
     */
    private void buildCommand() {
        
        //add command
        this.myCommands.put("Add", new IExecutable() {

            @Override
            public void Execute(String[] args) {
                try {
                    myCalendar.executeAddEvent(args);
                    onExecuted(args);
                } catch (CSWrongCommandFormatException ex) {
                    System.out.println(ex.getMessage());
                }
            }

            @Override
            public void onExecuted(String[] args) {
                myCalendar.onExecuted();
            }
        });
        
        //view command
        this.myCommands.put("View", new IExecutable() {

            @Override
            public void Execute(String[] args) {
                try{
                    myCalendar.executeViewEvent(args);
                    onExecuted(args);
                }catch(CSWrongCommandFormatException ex){
                    System.out.println(ex.getMessage());
                }
            }

            @Override
            public void onExecuted(String[] args) {
                 //do nothing
            }
        });
        
        //Load Command
        this.myCommands.put("Load", new IExecutable() {

            @Override
            public void Execute(String[] args) {
                try{
                    myCalendar.executeLoadCalendar(args);
                    onExecuted(args);
                }catch(CSWrongCommandFormatException ex){
                    System.out.println(ex.getMessage());
                }
            }

            @Override
            public void onExecuted(String[] args) {
                 myCalendar.onExecuted();
            }
        });
        
        //save
        this.myCommands.put("Save",new IExecutable() {

            @Override
            public void Execute(String[] args) {
                try {
                    myCalendar.executeSaveCalendar(args);
                    onExecuted(args);
                } catch (CSWrongCommandFormatException ex) {
                    System.out.println(ex.getMessage());
                }
            }

            @Override
            public void onExecuted(String[] args) {
                 //do nothing
            }
        });
        
        //delete event
        this.myCommands.put("Delete", new IExecutable() {

            @Override
            public void Execute(String[] args) {
                try {
                    myCalendar.executeDeleteEvent(args);
                    onExecuted(args);
                } catch (CSWrongCommandFormatException ex) {
                    System.out.println(ex.getMessage());
                }
            }

            @Override
            public void onExecuted(String[] args) {
                myCalendar.onExecuted();                        
            }
        });
        
        //show detail
        this.myCommands.put("ShowDetail",new IExecutable() {

            @Override
            public void Execute(String[] args) {
                try {
                    myCalendar.executeShowDetail(args);
                    onExecuted(args);
                } catch (CSWrongCommandFormatException ex) {
                    System.out.println(ex.getMessage());
                }
            }

            @Override
            public void onExecuted(String[] args) {
                //do nothing
            }
        });
        
        //print info
        this.myCommands.put("Info", new IExecutable() {

            @Override
            public void Execute(String[] args) {
                try {
                    myCalendar.executePrintInfo(args);
                    onExecuted(args);
                } catch (CSWrongCommandFormatException ex) {
                    System.out.println(ex.getMessage());
                }
            }

            @Override
            public void onExecuted(String[] args) {
                //do nothing
            }
        });
        
        this.myCommands.put("Undo", new IExecutable() {

            @Override
            public void Execute(String[] args) {
                try {
                    myCalendar.executeUndo(args);
                    onExecuted(args);
                } catch (CSWrongCommandFormatException ex) {
                    System.out.println(ex.getMessage());
                }
            }

            @Override
            public void onExecuted(String[] args) {                
            }
        });
        
        this.myCommands.put("Redo", new IExecutable() {

            @Override
            public void Execute(String[] args) {
                try {
                    myCalendar.executeRedo(args);
                    onExecuted(args);
                } catch (CSWrongCommandFormatException ex) {
                    System.out.println(ex.getMessage());
                }
            }

            @Override
            public void onExecuted(String[] args) {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        });
        
    }
}
